package qc.module.qms.dps.job;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import qc.common.core.exception.QCPromptException;
import qc.common.core.utils.LocalDateTimeUtil;
import qc.module.platform.dto.db.DBConnectionDto;
import qc.module.qms.dps.RestTemplatePlatform;
import qc.module.qms.dto.rawdata.QmsRawDataSyncResultDto;
import qc.module.qms.entity.QmsRawdataSync;
import qc.module.qms.service.rawdata.QmsRawdataSyncService;
import tech.powerjob.worker.core.processor.ProcessResult;
import tech.powerjob.worker.core.processor.TaskContext;
import tech.powerjob.worker.core.processor.sdk.BasicProcessor;

import java.time.LocalDateTime;
import java.util.HashMap;

/**
 * 原始数据同步Processor
 * 根据配置的从来源数据库表同步原始数据至QMS，通过调用QmsRawDataRecordService中的receive将原始数据发送至MQ或保存到原始数据表
 *
 * @author QuCheng Tech
 * @since 2025/11/23
 */
@Component
public class SyncRawDataJobProcessor implements BasicProcessor {
    private static final Logger logger = LoggerFactory.getLogger(SyncRawDataJobProcessor.class);

    @Autowired
    private QmsRawdataSyncService rawdataSyncService;

    @Autowired
    private RestTemplatePlatform restTemplatePlatform;

    /**
     * 维护一个数据库表编码和数据库连接信息对应关系集合，如果接收到的原始数据库表编码没有数据库连接信息调用platform中的接口获取
     */
    private static HashMap<String, DBConnectionDto> tableCodeConnectionMap;

    @Override
    public ProcessResult process(TaskContext taskContext) {
        LocalDateTime now = LocalDateTimeUtil.getNow();

        logger.debug("process taskContext.getJobParams=" + taskContext.getJobParams());

        String jobParams = taskContext.getJobParams();
        if (StringUtils.isBlank(jobParams)) {
            //返回ProcessResult中为false时会导致Powerjob一直重试，因此返回结果中设置为true
            //return new ProcessResult(false, "任务参数未设置，请在任务参数中指定一个同步的数据库表编码。");
            return new ProcessResult(true, "任务参数未设置，请在任务参数中指定一个同步的数据库表编码。");
        } else {
            //指定了数据库表编码才能进行同步，需要根据数据库表编码获取同步的记录（延续上次同步完成的记录往后进行同步）
            String tableCode = jobParams;
            //先初始化返回结果，设置是否成功标记为true
            QmsRawDataSyncResultDto result = new QmsRawDataSyncResultDto();
            result.setSuccess(true);
            //需要获取同步使用的源数据库连接和目标数据库连接
            //根据同步配置获取来源数据库表和目标数据库表连接信息
            DBConnectionDto srcCon = null;
            DBConnectionDto destCon = null;
            //获取同步entity并验证配置是否正确
            QmsRawdataSync syncEntity = rawdataSyncService.getEntity(tableCode);
            result = rawdataSyncService.validRawDataSyncConfig(syncEntity);
            //同步的配置验证不通过，不能进行数据同步操作；只有验证通过才能进行数据同步处理
            if (result.isSuccess() == true) {
                try {
                    srcCon = this.getTableConnection(syncEntity.getTablecode());
                } catch (QCPromptException e) {
                    result.setSuccess(false);
                    result.setMsg("获取同步的来源数据库连接信息异常，" + e.getMessage());
                }
                try {
                    destCon = this.getTableConnection(syncEntity.getDesttablecode());
                } catch (QCPromptException e) {
                    result.setSuccess(false);
                    result.setMsg("获取同步的目标数据库连接信息异常，" + e.getMessage());
                }
            }
            //来源和目标数据库连接信息均不为空时才进行同步处理
            if (result.isSuccess() == true) {
                if (srcCon == null) {
                    result.setSuccess(false);
                    result.setMsg("获取同步的来源数据库连接信息为空");
                }
                if (destCon == null) {
                    result.setSuccess(false);
                    result.setMsg("获取同步的目标数据库连接信息为空");
                }
            }
            //调用数据同步处理方法
            if (result.isSuccess() == true) {
                result = rawdataSyncService.autoSyncDatas(syncEntity, srcCon, destCon);
            }

            //根据数据同步的验证或处理结果进行更新
            String msg = "数据同步处理成功。";
            if (result.isSuccess() == true) {
                if (result.getCount() > 0x0) {
                    //更新最新数据同步的数据时标和处理时间
                    String endControlValueString = null;
                    //本次有进行同步的数据，更新同步的数据时标和控制使用的记录ID/时间
                    if (syncEntity.getCtrlbytm() != null && syncEntity.getCtrlbytm().booleanValue() == true) {
                        //按时间控制数据同步
                        msg = "数据同步处理成功，本次共同步数据[" + result.getCount() + "]条。";

                        if (result.getEndControlValue() != null) {
                            LocalDateTime endControlTime = (LocalDateTime) result.getEndControlValue();
                            endControlValueString = LocalDateTimeUtil.formatDateTime(endControlTime);
                            if (result.getBeginControlValue() != null) {
                                LocalDateTime beginControlTime = (LocalDateTime) result.getBeginControlValue();
                                String beginControlValueString = LocalDateTimeUtil.formatDateTime(beginControlTime);
                                msg += "本次同步时间段为[" + beginControlValueString + "]-[" + endControlValueString + "]";
                            }
                        }
                    } else {
                        //按数据ID数值控制数据同步
                        if (result.getEndControlValue() != null) {
                            endControlValueString = result.getEndControlValue().toString();
                            if (result.getBeginControlValue() != null) {
                                String beginControlValueString = result.getBeginControlValue().toString();
                                msg += "本次同步数据ID段为[" + beginControlValueString + "]-[" + endControlValueString + "]";
                            }
                        }
                    }

                    rawdataSyncService.updateLatestSyncDataTime(tableCode, now, msg, result.getEndDataTime(), endControlValueString);
                } else {
                    //同步数据处理成功，但没有需要同步的数据；只对最新同步处理时间进行更新
                    msg = "数据同步处理成功，本次没有需要进行同步的数据。";

                    //更新最新数据同步的处理时间
                    rawdataSyncService.updateLatestSyncHandleTime(tableCode, now, msg);
                }
            } else {
                //如果数据同步没有执行成功；只对最新同步处理时间进行更新
                msg = "数据同步处理失败，" + result.getMsg();

                //更新最新数据同步的处理时间
                rawdataSyncService.updateLatestSyncHandleTime(tableCode, now, msg);
            }
            return new ProcessResult(true, msg);
        }
    }

    /**
     * 根据指定的原始数据表编码获取对应的数据库连接；如果在保存的数据库连接Map中已有对应返回已有，如果没有调用platform接口获取后缓存到Map中
     *
     * @param tableCode 原始数据表编码
     * @return qc.module.platform.dto.db.DBConnectionDto
     * @author QuCheng Tech
     * @since 2025/11/1
     */
    DBConnectionDto getTableConnection(String tableCode) throws QCPromptException {
        if (StringUtils.isNotBlank(tableCode)) {
            if (tableCodeConnectionMap == null)
                tableCodeConnectionMap = new HashMap<>();

            //如果根据key存在已有的数据库连接，直接返回
            if (tableCodeConnectionMap.size() > 0x0 && tableCodeConnectionMap.containsKey(tableCode))
                return tableCodeConnectionMap.get(tableCode);

            //根据key获取不到已有的数据库连接，调用platform获取数据库连接信息
            DBConnectionDto tableConnection = restTemplatePlatform.getDbTableConnectionInfo(tableCode);
            if (tableConnection != null) {
                tableCodeConnectionMap.put(tableCode, tableConnection);

                return tableConnection;
            }
        }

        return null;
    }
}
